#ifndef _NMQ_H_
#define _NMQ_H_

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
/* define -------------------------------------------------------------*/

#define TX_FLAG_SENDED      (1 << 0)        // 已发送
#define TX_FLAG_RT          (1 << 1)        // 需要进行重新发送
#define TX_FLAG_TIMEOUT     (1 << 2)        // 是否超时标志位
#define TX_FLAG_MC          (1 << 3)        // 手动清除
#define TX_FLAG_IS_MALLOC   (1 << 4)        // 已经为MALLOC，不需要复制，使用该位时，如果为字符串，则长度要包含结束位

#define TX_ONCE_AC  0                           // 发一次，自动清除
#define TX_ONCE_MC  TX_FLAG_MC                  // 发一次，手动清除
#define TX_MULTI_AC TX_FLAG_RT                  // 发多次，自动清除，重发次数在TxMessageQueue.maxCount
#define TX_MULTI_MC (TX_FLAG_RT | TX_FLAG_MC)   // 发多次，手动清除

/* typedef ------------------------------------------------------------*/

struct Packet
{
    uint8_t *start;
    size_t length;
};


struct TxMessage
{
	struct Packet 	packet;
	uint32_t		time;
	uint32_t 		parameter;
	uint8_t 		flag;
    uint16_t 		countRetry;
};
struct RxMessage
{
	struct Packet 	packet;
};

struct TxMessageQueue
{
    struct TxMessage **listMessage;

	struct TxMessageQueueParameter
	{
		bool 		isDisorder;                        
		uint16_t 	countMaxRetry;                           
		uint16_t 	interval;                              
	}parameter;							
	
    uint8_t		_countTotal;                                  
    uint8_t 	_countUsed;                     		
	uint8_t 	_countMaxUsed;							
    uint8_t 	_index;   
	uint32_t 	_time; 	
    
    struct TxMessageQueueOperations
	{
		int (*transmit)(struct TxMessage *);       
	}ops;
	
	struct TxMessageQueueEvent
	{                             
		int (*clear)(struct TxMessage *, uint32_t);     
	}event;
};

struct RxMessageQueue
{
    struct RxMessage **listMessage;
	
	uint8_t		_countTotal;
    uint8_t 	_countUsed;  
	uint8_t 	_countMaxUsed;
    
	struct RxMessageQueueEvent
	{
		void (*new)(struct RxMessage *);                 
	}event;
}; 


/* macro --------------------------------------------------------------*/
/* variables ----------------------------------------------------------*/
/* function prototypes ------------------------------------------------*/
extern uint32_t NETick_Get(void);

void RxMsgQueue_Init(struct RxMessageQueue *mq, void **listMessage, size_t count);
int RxMsgQueue_Add(struct RxMessageQueue *mq, uint8_t *packet, size_t length, bool isMalloc);                      
void RxMsgQueue_Process(struct RxMessageQueue *mq);    
void RxMsgQueue_RegisterEventNew(struct RxMessageQueue *mq, void (*new)(struct RxMessage *));                                            

void TxMsgQueue_Init(struct TxMessageQueue *mq, void **listMessage, size_t count, int (*transmit)(struct TxMessage *msg));
int TxMsgQueue_Add(struct TxMessageQueue *mq, uint8_t *message, size_t length, uint8_t mode, uint32_t parameter);   
int TxMsgQueue_Process(struct TxMessageQueue *mq);           
void TxMsgQueue_ReigsterEventClear(struct TxMessageQueue *mq, int (*clear)(struct TxMessage *msg, uint32_t));                                

void TxMsgQueue_SetDisorder(struct TxMessageQueue *mq, bool enable);
void TxMsgQueue_SetRetry(struct TxMessageQueue *mq, int count);
void TxMsgQueue_SetInterval(struct TxMessageQueue *mq, int ms);

void TxMsgQueue_Free(struct TxMessageQueue *mq, int index);
void TxMsgQueue_FreeAll(struct TxMessageQueue *mq);
void TxMsgQueue_FreeByFunc(struct TxMessageQueue *mq, bool (*func)(struct TxMessage*, void *), void *para); 
void TxMsgQueue_FreeByParameter(struct TxMessageQueue *mq, uint32_t parameter);                                      

#endif
